package com.yy.wga.mp.module.order.manager;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yy.wga.mp.module.income.dto.OrderCommissionDTO;
import com.yy.wga.mp.module.order.entity.pojo.OrderGoodsDO;
import com.yy.wga.mp.module.order.entity.pojo.OrderGoodsSkuDO;
import com.yy.wga.mp.module.order.service.OrderGoodsService;
import com.yy.wga.mp.module.order.service.OrderGoodsSkuService;
import com.yy.wga.mp.module.wechat.feign.WechatMpFeign;
import com.yy.wga.mp.module.wechat.response.WechatGetAccessTokenResponse;
import com.yy.wga.common.core.exception.BusinessException;
import com.yy.wga.mp.common.interceptor.RequestUserHolder;
import com.yy.wga.mp.common.utils.common.IdUtils;
import com.yy.wga.mp.common.utils.common.JsonUtils;
import com.yy.wga.mp.common.utils.mapping.BeansUtils;
import com.yy.wga.mp.module.goods.common.utils.CommissionUtil;
import com.yy.wga.mp.module.merchant.entity.pojo.MerchantInfoDO;
import com.yy.wga.mp.module.merchant.service.MerchantInfoService;
import com.yy.wga.mp.module.order.api.OrderApi;
import com.yy.wga.mp.module.order.api.request.GetOrderInfoReq;
import com.yy.wga.mp.module.order.api.request.GetOrderListReq;
import com.yy.wga.mp.module.order.api.response.OrderInfoResp;
import com.yy.wga.mp.module.order.api.response.OrderListResp;
import com.yy.wga.mp.module.user.entity.pojo.UserBaseDO;
import com.yy.wga.mp.module.user.entity.pojo.UserWechatDO;
import com.yy.wga.mp.module.user.enums.EUserGrade;
import com.yy.wga.mp.module.user.service.UserBaseService;
import com.yy.wga.mp.module.user.service.UserWechatService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Author: gc
 * @Date: 2024/10/30
 * @Description:
 **/
@Slf4j
@Component
@RequiredArgsConstructor
public class PullOrderManager {
    private final OrderApi orderApi;
    private final OrderGoodsService orderGoodsService;
    private final OrderGoodsSkuService orderGoodsSkuService;
    private final MerchantInfoService merchantInfoService;
    private final UserWechatService userWechatService;
    private final UserBaseService userBaseService;
    private final WechatMpFeign wechatMpFeign;
    private final ApplicationEventPublisher eventPublisher;

    /**
     * 拉单，每次拉5分钟前的数据
     */
    @Transactional
    public void pullOrder(Integer minutes) {
        List<MerchantInfoDO> merchantInfoList = merchantInfoService.list();
        if (CollectionUtils.isEmpty(merchantInfoList)) {
            return;
        }
        for (MerchantInfoDO merchantInfoDO : merchantInfoList) {
            BaseRequestDTO baseRequestDTO = new BaseRequestDTO();
            baseRequestDTO.setAppKey(merchantInfoDO.getAppKey());
            RequestUserHolder.setBaseRequest(baseRequestDTO);
            Result<WechatGetAccessTokenResponse> accessTokenResult = wechatMpFeign.getChannelAccessToken();
            if (!accessTokenResult.isSuccess()) {
                throw new BusinessException(accessTokenResult.getMessage());
            }
            WechatGetAccessTokenResponse getAccessTokenResponse = accessTokenResult.getData();
            String accessToken = getAccessTokenResponse.getAccessToken();
            GetOrderListReq request = new GetOrderListReq();
            GetOrderListReq.TimeRange timeRange = new GetOrderListReq.TimeRange();
            long endTime = System.currentTimeMillis() / 1000;
            timeRange.setEndTime(endTime);
            timeRange.setStartTime(endTime - (minutes * 60));
            request.setUpdateTimeRange(timeRange);
            int pageSize = 30;
            request.setPageSize(pageSize);
            while (true) {
                log.info("拉单参数:{}", JSON.toJSONString(request));
                Map<String, Object> listDataMap = JSONObject.parseObject(JsonUtils.toJSONString(request), Map.class);
                JSONObject response = orderApi.getOrderList(accessToken, listDataMap);
                OrderListResp orderListResp = JSONObject.toJavaObject(response, OrderListResp.class);
                if (!orderListResp.isSuccsss()) {
                    throw new BusinessException("拉单失败:{}", JSON.toJSONString(response));
                }
                List<OrderListResp.Order> orderList = orderListResp.getList();
                log.info("拉单数量:{}", orderList.size());

                GetOrderInfoReq getOrderInfoReq = new GetOrderInfoReq();
                for (OrderListResp.Order orderResp : orderList) {
                    getOrderInfoReq.setOrderId(orderResp.getOrderId());
                    getOrderInfoReq.setSkuId(orderResp.getSkuId());
                    accessTokenResult = wechatMpFeign.getChannelAccessToken();
                    if (!accessTokenResult.isSuccess()) {
                        throw new BusinessException(accessTokenResult.getMessage());
                    }
                    getAccessTokenResponse = accessTokenResult.getData();
                    accessToken = getAccessTokenResponse.getAccessToken();
                    Map<String, Object> detailDataMap = JSONObject.parseObject(JsonUtils.toJSONString(getOrderInfoReq), Map.class);
                    log.info("查询订单详情参数:{}", JSON.toJSONString(detailDataMap));
                    JSONObject getOrderResponse = orderApi.get(accessToken, detailDataMap);
                    log.info("查询订单详情结果:{}", JSON.toJSONString(getOrderResponse));
                    OrderInfoResp orderInfoResp = JSONObject.toJavaObject(getOrderResponse, OrderInfoResp.class);
                    if (!orderInfoResp.isSuccsss()) {
                        throw new BusinessException("查询订单详情失败:{}", JSON.toJSONString(response));
                    }
                    OrderInfoResp.CommssionOrderInfo commssionOrder = orderInfoResp.getCommssionOrder();
                    OrderInfoResp.OrderDetail orderDetail = commssionOrder.getOrderDetail();
                    // 查询订单归属用户 先使用unionId  找不到则用sharerAppId
                    String unionid = orderDetail.getBuyerInfo().getUnionId();
                    UserWechatDO userWechat = userWechatService.getByUnionId(merchantInfoDO.getAppKey(), unionid);
                    if (Objects.isNull(userWechat)) {
                        // 使用分享者找到订单。 假设A是小程序用户  B不是 A分享给B  B购买  自购收益归A
                        OrderInfoResp.SharerInfo sharerInfo = orderDetail.getCommissionInfo().getSharerInfo();
                        if (Objects.nonNull(sharerInfo)) {
                            String sharerAppId = sharerInfo.getSharerAppId();
                            userWechat = userWechatService.getBySharerAppId(merchantInfoDO.getAppKey(), sharerAppId);

                        }
                    }
                    if (Objects.isNull(userWechat)) {
                        log.warn("未找到用户，orderNo:{}, unionid:{}", commssionOrder.getOrderId(), unionid);
                        continue;
                    }
                    UserBaseDO userBaseDO = userBaseService.getOne(new LambdaQueryWrapper<>(UserBaseDO.class)
                            .eq(UserBaseDO::getAppKey, merchantInfoDO.getAppKey())
                            .eq(UserBaseDO::getId, userWechat.getUserId())
                    );
                    if (userBaseDO == null) {
                        log.warn("订单未找到用户，orderNo:{}, userId:{}", commssionOrder.getOrderId(), userWechat.getUserId());
                        continue;
                    }
                    // 订单状态转换
                    // 10	待付款
                    // 20	待发货
                    //  21	部分发货
                    //  30	待收货
                    //  100	完成
                    //  200	全部商品售后之后，订单取消
                    //  250	未付款用户主动取消或超时未付款订单自动取消
                    Integer orderStatus = orderDetail.getOrderInfo().getOrderStatus();
                    // 未付款跳过
                    if (Objects.equals(10, orderStatus)) {
                        continue;
                    }
                    // 支付成功
                    int status;
                    if (Arrays.asList(20, 21, 30).contains(orderStatus)) {
                        status = 3;
                    } else if (Objects.equals(100, orderStatus)) {
                        status = 6;
                    } else if (Arrays.asList(200, 250).contains(orderStatus)) {
                        // 支付取消
                        status = 5;
                    } else {
                        log.error("返回未知订单状态,orderNo:{}, status:{}", commssionOrder.getOrderId(), orderStatus);
                        continue;
                    }
                    // 如果订单已存在则跳过
                    OrderGoodsDO orderGoods = orderGoodsService.getOne(new LambdaQueryWrapper<OrderGoodsDO>()
                            .eq(OrderGoodsDO::getAppKey, merchantInfoDO.getAppKey())
                            .eq(OrderGoodsDO::getThirdOrderNo, commssionOrder.getOrderId()).last(" LIMIT 1"));
                    if (orderGoods != null && orderGoods.getStatus().equals(status)) {
                        continue;
                    }

                    // 返回订单信息、携带商品不全，直接回查数据库。得到完整商品信息
                    OrderInfoResp.ProductInfo productInfo = orderDetail.getProductInfo();
                    // 保存订单
                    OrderGoodsDO saveOrderGoods = new OrderGoodsDO();
                    if (orderGoods != null) {
                        saveOrderGoods.setId(orderGoods.getId());
                        saveOrderGoods.setOrderNo(orderGoods.getOrderNo());
                    } else {
                        saveOrderGoods.setOrderNo(IdUtils.uuid());
                    }
                    saveOrderGoods.setStatus(status);
                    // 订单没返回支付时间，则使用创建时间
                    if (status == 3) {
                        // 已支付
                        if (Objects.isNull(orderGoods) || Objects.isNull(orderGoods.getPayTime())) {
                            saveOrderGoods.setPayTime(new Date(commssionOrder.getUpdateTime() * 1000));
                        }
                    }
                    if (status == 6) {
                        // 已完成
                        if (Objects.isNull(orderGoods) || Objects.isNull(orderGoods.getSuccessTime())) {
                            saveOrderGoods.setSuccessTime(new Date(commssionOrder.getUpdateTime() * 1000));
                        }
                    }
                    if (status == 5) {
                        saveOrderGoods.setCancelTime(new Date());
                    }
                    saveOrderGoods.setThirdOrderNo(commssionOrder.getOrderId());
                    // 支付金额
                    Integer actualPayment = productInfo.getActualPayment();
                    // 支付佣金
                    Integer serviceAmount = orderDetail.getCommissionInfo().getServiceAmount();


                    saveOrderGoods.setFinalPrice(actualPayment);
                    saveOrderGoods.setOriginPrice(actualPayment);
                    saveOrderGoods.setFromUserId(userWechat.getUserId());
                    saveOrderGoods.setThirdOrderNo(commssionOrder.getOrderId());

                    // 计算佣金
                    EUserGrade userGrade = EUserGrade.getByType(userBaseDO.getGrade(), userBaseDO.getLevel());
                    Integer commissionValue = CommissionUtil.calcCommissionValue(serviceAmount, userGrade);
                    saveOrderGoods.setCommissionValue(commissionValue);
                    saveOrderGoods.setProductId(productInfo.getProductId());
                    saveOrderGoods.setSkuId(commssionOrder.getSkuId());
                    saveOrderGoods.setTitle(productInfo.getTitle());
                    saveOrderGoods.setThumbImg(productInfo.getThumbImg());
                    saveOrderGoods.setAppKey(merchantInfoDO.getAppKey());
                    saveOrderGoods.setPayTime(new Date(commssionOrder.getCreateTime() * 1000));
                    orderGoodsService.saveOrUpdate(saveOrderGoods);

                    // sku信息保存
                    if (orderGoods == null) {
                        OrderGoodsSkuDO orderGoodsSku = new OrderGoodsSkuDO();
                        orderGoodsSku.setOrderNo(saveOrderGoods.getOrderNo());
                        // 订单没返回支付金额 使用原商品信息
                        orderGoodsSku.setFinalPrice(actualPayment);
                        orderGoodsSku.setOriginPrice(actualPayment);
                        orderGoodsSku.setNumber(1);

//                        GoodsSpuDO.Sku goodSpuSku = goodsSpu.getSkus().stream().filter(sku -> sku.getSkuId().equals(commssionOrder.getSkuId())).findFirst().orElse(null);
//                        if (Objects.nonNull(goodSpuSku)) {
//                            List<OrderGoodsSkuDO.Attr> orderGoodsSkuAttrs = new ArrayList<>();
//                            for (GoodsSpuDO.Attr attr : goodSpuSku.getSkuAttrs()) {
//                                OrderGoodsSkuDO.Attr orderGoodsSkuAttr = new OrderGoodsSkuDO.Attr();
//                                orderGoodsSkuAttr.setAttrKey(attr.getAttrKey());
//                                orderGoodsSkuAttr.setAttrValue(StringUtils.join(";", attr.getAttrValue()));
//                                orderGoodsSkuAttrs.add(orderGoodsSkuAttr);
//                            }
//                            orderGoodsSku.setSkuAttrs(orderGoodsSkuAttrs);
//                        }

                        orderGoodsSku.setSkuId(commssionOrder.getSkuId());
                        orderGoodsSku.setSpuId(productInfo.getProductId());
                        orderGoodsSku.setTitle(productInfo.getTitle());
                        orderGoodsSku.setThumbImg(productInfo.getThumbImg());
                        orderGoodsSku.setStatus(status);
                        orderGoodsSku.setAppKey(saveOrderGoods.getAppKey());
                        orderGoodsSku.setUserId(userWechat.getUserId());
                        orderGoodsSkuService.save(orderGoodsSku);
                    } else {
                        orderGoodsSkuService.update(new LambdaUpdateWrapper<OrderGoodsSkuDO>()
                                .eq(OrderGoodsSkuDO::getAppKey, saveOrderGoods.getAppKey())
                                .eq(OrderGoodsSkuDO::getOrderNo, saveOrderGoods.getOrderNo())
                                .set(OrderGoodsSkuDO::getStatus, status));
                    }

                    // 分佣

                    OrderCommissionDTO orderCommissionDTO = BeansUtils.map(saveOrderGoods, OrderCommissionDTO.class);
                    orderCommissionDTO.setAppKey(merchantInfoDO.getAppKey());
                    // 可分佣金额
                    orderCommissionDTO.setCommissionValue(serviceAmount);
                    orderCommissionDTO.setFromUserId(userWechat.getUserId());
                    orderCommissionDTO.setStatus(status);
                    eventPublisher.publishEvent(orderCommissionDTO);
                }

                if (orderList.size() < pageSize) {
                    break;
                }
                request.setNextKey(orderListResp.getNextKey());
            }
        }
    }
}
